Xamarin.Forms イメージ
1 はじめに
Xamarin.Formsの、ビューの1つであるImageは、画像を表示するためのコントロールです。
参考:Xamarin Developers Guide 「Working with Images」
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/images/
2 イメージの指定 Source
プロパティSource(ImageSource型)には、表示する画像を指定します。
指定の方法は、画像の配置場所によって次の3種類があります。
各プラットフォーム(ローカル) | 各プラットフォームのプロジェクトにリソースとして配置します。 |
インターネット | インターネット上に配置し、ダウンロードして使用します。 |
共有プロジェクト(ローカル) | 共有プロジェクト(PCL)にリソースとして配置します。 |
(1) 各プラットフォーム上に配置する場合
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { Content = new Image { Source = "classmethod.png" //この書き方でもOK //Source = ImageSource.FromFile("classmethod.png") //この書き方でもOK //Source = FileImageSource.FromFile("classmethod.png") }; } }
Android | iOS | Windows Phone |
ローカルの画像ファイルは、Androidの場合は、Resources/Drawableの階層下、iOSの場合は、Resourcesの階層下に配置します。WindowsPhoneではカレントになりますが、特定のフォルダにまとめることも可能です。
なおコードは、PCL(一か所)で書けますが、画像ファイルは、プラットフォームごと(3か所)に置く必要があります。
Android | iOS | Windows Phone |
(2) インターネット上に配置する場合
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage{ class MyPage : ContentPage { public MyPage() { var uri = "http://www.sapporoworks.ne.jp/main.jpg"; Content = new Image { Source = ImageSource.FromUri(new Uri(uri)) //この書き方でもOK //Source = uri //この書き方でもOK //Source = new UriImageSource { // Uri = new Uri(uri), // CachingEnabled = false //} }; } } }
UriImageSourceには、キャッシュ機能があります。
Android | iOS | Windows Phone |
(3) 共有プロジェクトに配置する場合
PCLのリソースとして定義すると、画像の配置も一か所だけでよくなります。
ディレクトリなどの階層下にまとめるのも自由なので、Formsを使用するなら、この要領が一番お薦めです。
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { Content = new Image { Source = ImageSource.FromResource("App1.Images.classmethod.png") }; } }
なお、画像のビルドアクションは、「埋め込まれたリソース」に設定する必要があります。 ビルドアクションは、画像を右クリックして指定できます。
Android | iOS | Windows Phone |
3 イメージの配置 Aspect
Imageのエリアに画像をどのように展開するかを、プロパティAspectに設定します。
Aspect.AspectFill(デフォルト) | 画像の縦横比を保持したまま、Imageに収まるように縮小する |
Aspect.AspectFit | 画像の縦横比を保持したまま、Image全体に表示する(画像の一部が欠ける) |
Aspect.Fill | 画像の縦横比を無視して、Image全体に表示する(画像の縦横比が壊れる) |
サンプルは、3種類のAspect値によるImageの比較です。
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { var width = Device.OnPlatform(360, 360, 480); var height = Device.OnPlatform(120, 120, 180); var layout = new AbsoluteLayout(); const int x = 10; var y = 30; foreach (Aspect aspect in Enum.GetValues(typeof(Aspect))) { layout.Children.Add(new Label { Text = aspect.ToString() }, new Point(x, y)); y += 30; layout.Children.Add(CreateImage(aspect), new Rectangle(x, y, width, height)); y += height + 30; } Content = layout; } static Image CreateImage(Aspect aspect) { var image = new Image { Source = ImageSource.FromResource("App1.Images.classmethod.png"), BackgroundColor = Color .FromRgb(240,240,240), Aspect = aspect }; return image; } }
Android | iOS | Windows Phone |
透明度 Opacity
プロパティOpacity(0.0~1.0)で画像の透明度を指定します。 サンプルは、同じ画像を5段階の透明度で配置したものです。
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { //アブソレートレイアウトの生成 var layout = new AbsoluteLayout(); //画像とラベルを5個配置 var y = 40; var x = 20;//左余白 const int size = 120; // 画像のサイズ for (var i = 0; i < 5; i++) { var opacity = 0.25 * i; //透明度 //透明度を表示するためのラベルを生成 var label = new Label { Text = String.Format("Opacity={0}", opacity) }; //ラベルをレイアウトに配置 layout.Children.Add(label, new Point(x, y)); y += 10; // ラベルの分のオフセットを移動 //前景画像の作成 var imageFront = new Image { Source = ImageSource.FromResource("App1.Images.classmethod.png"), Aspect = Aspect.Fill, Opacity = opacity,//透明度 }; //前景画像をレイアウトに配置 layout.Children.Add(imageFront, new Rectangle(x, y,size,size)); // 配置のオフセットを移動 y += size-50; x += 50; } Content = layout; //アブソレートレイアウトをContentにセットする } }
Android | iOS | Windows Phone |
4 レイアウト OptionLayout
レイアウトは、イメージに固有のプロパティではありませんが、参考のため列挙させて頂きます。
(1) Center・End・Fill・Start
HorizontalOptions(横方向)及びVerticalOptions(縦方向)にLayoutOptionを指定することで、その配置を指定できます。
- Center 中央揃え
- End 最終(右)揃え
- Fill 全部使用
- Start 最初(左)揃え
次のサンプルは、HorizontalOptions(横方向)に各レイアウトを指定したものです。
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { var ar = new[]{ LayoutOptions.Center, LayoutOptions.End, LayoutOptions.Fill, LayoutOptions.Start}; var layout = new StackLayout(); foreach (var op in ar) { layout.Children.Add(new Label { Text = op.Alignment.ToString(), // LayoutOption名を表示する }); var img = new Image { Source = ImageSource.FromResource("App1.Images.classmethod.png"), BackgroundColor = Color.FromRgb(240,240,240), HorizontalOptions = op, // 4種類のLayoutOptionをそれぞれ設定する WidthRequest = 100, HeightRequest = 100 }; layout.Children.Add(img); } Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0); Content = layout; } }
Android | iOS | Windows Phone |
(2) Fill・FillAndExpand
レイアウトオプションには、AndExpandが付いたものと、そうでないものがありますが、この違いは、余白を埋めるかどうかにあります。
次の例は、スタックレイアウトに同じイメージを3つ並べ、真ん中のイメージに、Fillを指定した場合とFillAndExpandを指定した場合の違いを示したものです。
public class App : Application { public App() { MainPage = new MyPage(); } } class MyPage : ContentPage { public MyPage() { var layout = new StackLayout(); for (var i = 0; i < 3; i++) { var img = new Image { Source = ImageSource.FromResource("App1.Images.classmethod.png"), BackgroundColor = Color.FromRgb(240, 240, 240) }; if (i == 1) { img.VerticalOptions = LayoutOptions.Fill; // Fillの場合 //img.VerticalOptions = LayoutOptions.FillAndExpand; // FillAndExpandの場合 } layout.Children.Add(img); } Content = layout; } }
Fillの場合 | FillAndExpandの場合 |
5 まとめ
今回は、Xamarin.Fomrsにおけるイメージビューについて確認してみました。 イメージについては、枯れているというか、必要な機能は網羅されているので、これをレンダラー拡張して・・・というようなパターンは少ないかと思います。
また、「ImageSource.FromResource」でリソース指定することで、共通プロジェクトだけで画像リソースを管理できるので、できれはこの方法を積極的に使用するべきではと思います。
本記事は、2015年12月29日現在で最新の Xamarin.Forms 2.0.0.6490を使用して作成されています。
6 参考リンク
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
Xamarin記事一覧(SAPPOROWORKSの覚書)